home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
xinu.arc
/
XINUC3.C
< prev
Wrap
Text File
|
1986-01-03
|
15KB
|
567 lines
/* queue.c - dequeue, enqueue p. 46 */
# include <conf.h>
# include <kernel.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* enqueue -- insert an item at the tail of a list
*-----------------------------------------------------------------------------
*/
int enqueue(item,tail)
int item; /* item to enqueue on a list */
int tail; /* index in q of list tail */
{
struct qent *tptr; /* points to tail entry */
struct qent *mptr; /* points to item entry */
tptr = &q[tail];
mptr = &q[item];
mptr->qnext = tail;
mptr->qprev = tptr->qprev;
q[tptr->qprev].qnext = item;
tptr->qprev = item;
return(item);
}
/*-----------------------------------------------------------------------------
* dequeue -- remove an item from a list and return it
*-----------------------------------------------------------------------------
*/
int dequeue(item)
int item;
{
struct qent *mptr; /* pointer to q entry for item */
mptr = &q[item];
q[mptr->qprev].qnext = mptr->qnext;
q[mptr->qnext].qprev = mptr->qprev;
return(item);
}
/* rdisk.c - rdinit rdopen rdread rdwrite */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
# ifdef Ndsk
struct dsblk dstab[Ndsk];
# endif
int dskdbp, dskrbp;
/*-----------------------------------------------------------------------------
* rdinit -- initialize ram disk device
*-----------------------------------------------------------------------------
*/
rdinit(devptr)
struct devsw *devptr;
{
struct dsblk *dsptr;
struct dtc *dtptr;
int status;
int ps;
ps = disable();
dsptr = &dstab[devptr->dvminor];
devptr->dvioblk = (char *)dsptr;
dsptr->dcsr = (struct dtc *)devptr->dvcsr;
dsptr->dreqlst = DRNULL;
dsptr->dnum = devptr->dvnum;
dsptr->dibsem = screate(1);
dsptr->dflsem = screate(1);
dsptr->ddirsem = screate(1);
dsptr->dnfiles = 0;
dsptr->ddir = (char *)getbuf(dskdbp);
è /* read directory block; setup read command then start interface */
rdread ( devptr, dsptr->ddir, DIRBLK );
restore(ps);
return(OK);
}
/*-----------------------------------------------------------------------------
* rdopen -- open/create a file on the specified ram disk device
*-----------------------------------------------------------------------------
*/
rdopen(devptr, filenam, mode)
struct devsw *devptr;
char *filenam;
char *mode;
{
struct dir *dirptr;
struct flblk *flptr;
struct fdes *fdptr;
DBADDR dba;
int mbits, findex;
int retcode;
int ps;
extern struct fdes *dfdsrch();
ps = disable();
dirptr = dsdirec(devptr->dvnum);
if ((mbits=dfckmd(mode)) == SYSERR)
retcode = SYSERR;
else if ((fdptr=dfdsrch(devptr->dvioblk,filenam,mbits))
== (struct fdes *)SYSERR)
retcode = SYSERR;
else if ((findex=dfalloc()) == SYSERR)
retcode = SYSERR;
else {
flptr = &fltab[findex];
flptr->fl_dev = devptr->dvnum;
flptr->fl_dent = fdptr;
flptr->fl_mode = mbits & FLRW;
flptr->fl_iba = fdptr->fdiba;
ibget(flptr->fl_dev,flptr->fl_iba,&(flptr->fl_iblk));
flptr->fl_pos = 0L;
flptr->fl_dch = FALSE;
dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum = 0];
if (dba != DBNULL) {
read(flptr->fl_dev, flptr->fl_buff, dba);
flptr->fl_bptr = flptr->fl_buff;
} else
flptr->fl_bptr = &flptr->fl_buff[DBUFSIZ];
retcode = flptr->fl_id;
}
restore(ps);
return(retcode);
}è
/*-----------------------------------------------------------------------------
* rdread -- read from ram disk
*-----------------------------------------------------------------------------
*/
rdread(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
char *from, *to;
int i;
from = (char *)((long)block * (long)DBUFSIZ + (long)devptr->dvcsr );
to = buff;
for ( i = 0; i < DBUFSIZ; i++ ) {
*to++ = *from++;
}
return(OK);
}
/*-----------------------------------------------------------------------------
* rdwrite -- write to ram disk
*-----------------------------------------------------------------------------
*/
rdwrite(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
char *from, *to;
int i;
from = buff;
to = (char *)((long)block * (long)DBUFSIZ + (long)devptr->dvcsr );
for ( i = 0; i < DBUFSIZ; i++ ) {
*to++ = *from++;
}
freebuf(buff);
return(OK);
}
/* read.c - read p. 145 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* read -- read one or more bytes from a device
*-----------------------------------------------------------------------------
*/
read(descrp, buff, count)
int descrp, count;
char *buff;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvread)(devptr,buff,count));
}
/* ready.c - ready p. 62 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* ready -- make a process eligible for CPU service
*-----------------------------------------------------------------------------
*/
int ready (pid, resch)
int pid; /* id of process to make ready */
int resch; /* reschedule afterward? */
{
register struct pentry *pptr;
if (isbadpid(pid))
return(SYSERR);
pptr = &proctab[pid];
pptr->pstate = PRREADY;
insert(pid,rdyhead,pptr->pprio);
if (resch)
resched();
return(OK);
}
/* receive.c - receive p. 97 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
/*-----------------------------------------------------------------------------
* receive -- wait for a message and return it
*-----------------------------------------------------------------------------
*/
SYSCALL receive()
{
struct pentry *pptr;
int msg;
char ps;
disable(ps);
pptr = &proctab[currpid];
if (pptr->phasmsg == 0) { /* if no message, wait for one */
pptr->pstate = PRRECV;
resched();
}
msg = pptr->pmsg; /* retrieve message */
pptr->phasmsg = 0;
restore(ps);
return(msg);
}
/* recvclr.c - recvclr p. 98 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
/*-----------------------------------------------------------------------------
* recvclr -- clear messages, returning waiting message ( if any )
*-----------------------------------------------------------------------------
*/
SYSCALL recvclr()
{
char ps;
int msg;
disable(ps);
if (proctab[currpid].phasmsg) { /* existing message */
proctab[currpid].phasmsg = 0;
msg = proctab[currpid].pmsg;
} else
msg = OK;
restore(ps);
return(msg);
}
/* resched.c - resched p. 58 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* resched -- reschedule processor to highest priority ready process
*
* Notes: Upon entry, currpid gives current process id.
* Proctab[currpid].pstate gives correct NEXT state for
* current process if other than PRREADY.
*-----------------------------------------------------------------------------
*/
int resched()
{
register struct pentry *optr; /* pointer to old process entry */
register struct pentry *nptr; /* pointer to new process entry */
/* no switch needed if current process priority higher than next */
if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
(lastkey(rdytail)<optr->pprio))
return ( OK );
/* force context switch */
if (optr->pstate == PRCURR) {
optr->pstate = PRREADY;
insert(currpid,rdyhead,optr->pprio);
}
/* remove highest priority process at end of ready list */
nptr = &proctab[ (currpid = getlast(rdytail)) ];
nptr->pstate = PRCURR; /* mark it currently running */
# ifdef RTCLOCK
preempt = QUANTUM; /* reset preemption counter */
# endif
ctxsw(optr->pregs,nptr->pregs);
/* the old process returns here when resumed. */
return(OK);
}
/* resume.c - resume p. 66 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
/*-----------------------------------------------------------------------------
* resume -- unsuspend a process, making it ready; return the priority
*-----------------------------------------------------------------------------
*/
SYSCALL resume(pid)
int pid;
{
char ps; /* saved processor status */
struct pentry *pptr; /* pointer to proccess table entry */
int prio; /* priority to return */
disable(ps);
if (isbadpid(pid) || (pptr = &proctab[pid])->pstate != PRSUSP) {
restore(ps);
return(SYSERR);
}
prio = pptr->pprio;
ready(pid, RESCHYES);
restore(ps);
return(prio);
}
/* screate.c - screate, newsem p. 88 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
# include <sem.h>
/*-----------------------------------------------------------------------------
* screate -- create and initialize a semaphore, returning its id
*-----------------------------------------------------------------------------
*/
SYSCALL screate(count)
int count; /* initial count (>=0) */
{
char ps;
int sem;
disable(ps);
if ( count<0 || (sem=newsem())==SYSERR ) {
restore(ps);
return(SYSERR);
}
semaph[sem].semcnt = count;
/* sqhead and sqtail were initialized at system startup */
restore(ps);
return(sem);
}
/*-----------------------------------------------------------------------------
* newsem -- allocate an unused semaphore and return its index
*-----------------------------------------------------------------------------
*/
LOCAL newsem()
{
int sem;
int i;
for (i=0 ; i<NSEM ; i++) {
sem = nextsem--;
if (nextsem < 0)
nextsem = NSEM-1;
if (semaph[sem].sstate==SFREE) {
semaph[sem].sstate = SUSED;
return(sem);
}
}
return(SYSERR);
}
/* sdelete.c - sdelete p. 89 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
# include <sem.h>
/*-----------------------------------------------------------------------------
* sdelete -- delete a semaphore by releasing its table entry
*-----------------------------------------------------------------------------
*/
SYSCALL sdelete(sem)
int sem;
{
char ps;
int pid;
struct sentry *sptr; /* address of sem to free */
disable(ps);
if (isbadsem(sem) || semaph[sem].sstate==SFREE) {
restore(ps);
return(SYSERR);
}
sptr = &semaph[sem];
sptr->sstate = SFREE;
if (nonempty(sptr->sqhead)) { /* free waiting process */
while ((pid=getfirst(sptr->sqhead)) != EMPTY)
ready(pid,RESCHNO);
resched();
}
restore(ps);
return(OK);
}
/* seek.c - seek p. 148 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* seek -- position a device (very common special case of control)
*-----------------------------------------------------------------------------
*/
seek(descrp, pos)
int descrp;
long pos;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvseek)(devptr,pos));
}
/* send.c - send p. 96 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
/*-----------------------------------------------------------------------------
* send -- send a message to another process
*-----------------------------------------------------------------------------
*/
SYSCALL send(pid, msg)
int pid;
int msg;
{
struct pentry *pptr; /* receiver's process table address */
char ps;
disable(ps);
if (isbadpid(pid) || ((pptr= &proctab[pid])->pstate == PRFREE)
|| pptr->phasmsg != 0) {
restore(ps);
return(SYSERR);
}
pptr->pmsg = msg; /* deposit message */
pptr->phasmsg++;
if (pptr->pstate == PRRECV) /* if receiver waits, start it */
ready(pid, RESCHYES);
restore(ps);
return(OK);
}
/* signal.c - signal p. 86 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
# include <sem.h>
/*-----------------------------------------------------------------------------
* signal -- signal a semaphore, releasing one waiting process
*-----------------------------------------------------------------------------
*/
SYSCALL signal(sem)
register int sem;
{
register struct sentry *sptr;
char ps;
disable(ps);
if (isbadsem(sem) || (sptr = &semaph[sem])->sstate==SFREE) {
restore(ps);
return(SYSERR);
}
if ((sptr->semcnt++) < 0)
ready(getfirst(sptr->sqhead),RESCHYES);
restore(ps);
return(OK);
}
/* sleep.c - sleep p. 132 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
# include <sleep.h>
/*-----------------------------------------------------------------------------
* sleep -- delay the calling process n seconds
*-----------------------------------------------------------------------------
*/
SYSCALL sleep(n)
int n;
{
if (n<0 || clkruns==0)
return(SYSERR);
if (n == 0) {
resched();
return(OK);
}
while (n >= 1000) {
sleep10(10000);
n -= 1000;
}
if (n > 0)
sleep10(10*n);
return(OK);
}
/* sleep10.c - sleep10 p. 129 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <q.h>
# include <sleep.h>
/*-----------------------------------------------------------------------------
* sleep10 -- delay the caller for a time specified in tenths of seconds
*-----------------------------------------------------------------------------
*/
SYSCALL sleep10(n)
int n;
{
char ps;
if (n < 0 || clkruns==0)
return(SYSERR);
if (n == 0) {
resched(); /* sleep10(0) -> end time slice */
return(OK);
}
disable(ps);
insertd(currpid,clockq,n);
slnempty = TRUE;
sltop = &q[q[clockq].qnext].qkey;
proctab[currpid].pstate = PRSLEEP;
resched();
restore(ps);
return(OK);
}